#!/usr/bin/python

from twisted.conch.telnet import StatefulTelnetProtocol, Telnet
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.internet.endpoints import TCP4ClientEndpoint
import twisted.conch.telnet as telnet
import binascii, struct
import sys

DOAUTH = chr(37)
NEWENV = chr(39)
BINTRNS = chr(0)

CMDSTATUS = True

TD= lambda x: x+1 #TELNET DESIRE
TC = lambda x: x+2 #TELNET COMMAND

def getTerminalSize():
    import os
    env = os.environ
    def ioctl_GWINSZ(fd):
        try:
            import fcntl, termios, struct, os
            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
        '1234'))
        except:
            return
        return cr
    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
    if not cr:
        try:
            fd = os.open(os.ctermid(), os.O_RDONLY)
            cr = ioctl_GWINSZ(fd)
            os.close(fd)
        except:
            pass
    if not cr:
        cr = (env.get('LINES', 25), env.get('COLUMNS', 80))

        ### Use get(key[, default]) instead of a try/catch
        #try:
        #    cr = (env['LINES'], env['COLUMNS'])
        #except:
        #    cr = (25, 80)
    Lineas = int(cr[0])
    Columnas = int(cr[1])
    #return int(cr[1]), int(cr[0])
    return Lineas, Columnas 

class MyTelnetProtocol(Telnet):
    ImperativeComand = [telnet.SGA, telnet.ECHO, telnet.NAWS]
    
    
    def __WillProcessor(self, WillData):
        for i in WillData:
            if i == telnet.ECHO:
                print "Will Echo"
            elif i == telnet.SGA:
                print "Will Suppress Go a Head"
            elif i == BINTRNS:
                print "Will Binary Transmision"
    
    def __DoProcessor(self, DoData):
        for i in DoData:
            if i == DOAUTH:
                print "Do Do Authentication"
            if i == NEWENV:
                print "Do New Environment"
            if i == telnet.NAWS:
                print "Do Negotiation about Windows Size"
                print "Windows Size is Lineas %d Columnas %d\n" % (getTerminalSize())
            if i == BINTRNS:
                print "Do Binary transmision"
    
    def dataReceived(self, data):
        print "recivimos algo"
        willBuffer = []
        DoBuffer = []
        #print repr(data)
        #print data.count(telnet.IAC)
        #print struct.unpack('c'*21, data)
        for i in range(len(data)):
            if data[i] == telnet.IAC:
                if data[TD(i)] == telnet.WILL:
                    #print "Tenemos un will"
                    willBuffer.append(data[TC(i)])
                elif data[TD(i)] == telnet.DO:
                    #print "Tenemos un DO"
                    DoBuffer.append(data[TC(i)])
                else:
                    print "DAtos"
        #VALIDAR ANTES DE MANDAR A LOS PROCESADORES QUE SE TIENE ALGO EN WILL
        if len(willBuffer) > 0:
            print repr(willBuffer)
            self.__WillProcessor(willBuffer)
        if len(DoBuffer) > 0:
            print repr(DoBuffer)
            self.__DoProcessor(DoBuffer)          
        #print binascii.b2a_hex(data)
        #for i in binascii.b2a_hex(data):
         #   print i[i+2] + '\n'
            
    def connectionMade(self):
        print "hemos conectado"
        #self.sendLine('Helo')
        #StatefulTelnetProtocol.connectionMade(self)


class MyTelnetFactory(ReconnectingClientFactory):
    protocol = MyTelnetProtocol
    TelServStatus = {}
    ClientStatus = {}
    
    def clientConnectionLost(self, conector, ureason):
        print "Hemos perdido conexion con el cliente"
        ReconnectingClientFactory.clientConnectionLost(self, conector, ureason)
        
    def clientConnectionFailed(self, connector, reason):
        print "Houston tenemos un problema"
        ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)

if __name__ == '__main__':
    from twisted.internet import reactor
    
    def TestProtocol(MyProtocolsTest):
        print "TestProtocols"
        testunit = MyProtocolsTest
        reactor.callLater(5, testunit.clearBuffer)
        print "Limpiamos"
        reactor.callLater(10, testunit.write, 'dir')
    
    host = '192.168.213.143'
    port = 23
    client = TCP4ClientEndpoint(reactor, host, port)
    #reactor.connectTCP(host, port, MyTelnetFactory())
    print "aqui"
    d = client.connect(MyTelnetFactory())
    d.addCallback(TestProtocol)
    reactor.run()
